import fs from "node:fs";
import path from "node:path";
import { SourceMap } from "../sourcemap/sourcemap.js";

tsc({
  sourcemap: "file", // "inline" | false | true | "file"
  input: "./src/main.ts",
  output: "./src/main.js",
});

/**
 * compile typescript to javascript
 * simply remove typescript type annotation
 * generate javascript sourcemap
 */
export async function tsc(options) {
  const input = path.resolve(options.input);
  const output = path.resolve(options.output);

  const src = await fs.promises.readFile(input, "utf-8");

  // generate sourcemap
  const sourcemap = new SourceMap({
    file: path.basename(output),
    sources: [path.basename(input)],
    sourcesContent: [src],
  });

  let target = "";
  const lines = src.split("\n");
  let i = 0;
  while (i < lines.length) {
    const line = lines[i];

    // comment type annotation
    const newLine = line.replaceAll(
      /:\s*(number|string|boolean)/g,
      (match, type) => {
        return `/*${type}*/`;
      }
    );
    target += newLine + "\n";

    // line level mapping
    sourcemap.addSegment(i, 0, 0, i, 0);

    i++;
  }

  // attach sourcemap comment
  if (options.sourcemap === "file") {
    target += "\n//# sourceMappingURL=" + path.basename(output) + ".map";
    await fs.promises.writeFile(output + ".map", sourcemap.toString(4));
  } else if (options.sourcemap === "inline" || options.sourcemap === true) {
    target += "\n//# sourceMappingURL=" + sourcemap.toURL();
  }

  // write file
  await fs.promises.writeFile(output, target);
}
